﻿using System;
namespace SUMO.MediaBrowser.Foundation
{
    public class WcfFileUploader : IFileUploader
    {
        private readonly TabImage tabImage;
        private bool _canceling;
        private bool _processing;
        private string _uploadedFileProcessorType;

        public WcfFileUploader(TabImage tabImage)
        {
            this.tabImage = tabImage;
        }

        #region Implementation of IFileUploader

        /// <summary>
        /// Starts the upload; can pass an optional extra parameter that is sent to the server with each chunk.
        /// </summary>
        /// <param name="uploadedFileProcessorType"></param>
        public void StartUpload(string uploadedFileProcessorType)
        {
            _uploadedFileProcessorType = uploadedFileProcessorType;
            StartUpload(false, false);
        }

        public event EventHandler UploadFinished;
        public event EventHandler UploadCancelled;
        public event EventHandler<UploadErrorOccurredEventArgs> UploadErrorOccurred;
        public event EventHandler<UploadDataSentArgs> UploadDataSent;
        public event EventHandler UploadProcessingStarted;

        #endregion

        private void OnUploadFinished()
        {
            EventHandler handler = UploadFinished;
            if (handler != null)
                handler(this, null);
        }

        private void OnUploadCanceled()
        {
            EventHandler handler = UploadCancelled;
            if (handler != null)
                handler(this, null);
        }

        private void OnUploadErrorOccurred(UploadErrorOccurredEventArgs e)
        {
            EventHandler<UploadErrorOccurredEventArgs> handler = UploadErrorOccurred;
            if (handler != null)
                handler(this, e);
        }

        private void OnUploadDataSent(UploadDataSentArgs e)
        {
            EventHandler<UploadDataSentArgs> handler = UploadDataSent;
            if (handler != null)
                handler(this, e);
        }

        private void OnUploadProcessingStarted()
        {
            EventHandler handler = UploadProcessingStarted;
            if (handler != null)
                handler(this, null);
        }

        private void StartUpload(bool cancel, bool process)
        {
            //ImageLibraryServiceClient client = new ImageLibraryServiceClient();
            //client.UploadImageDataCompleted += UploadImageDataCompleted;
            //client.UploadImageDataForLocalImageCompleted += UploadImageDataForLocalImageCompleted;
            //if (tabImage.Parent.Reference == null)
            //{
            //    client.UploadImageDataForLocalImageAsync(tabImage.ImageGuid, tabImage.ImageStreamBuffer, cancel, process);
            //    OnUploadDataSent(new UploadDataSentArgs(tabImage.ImageStreamBuffer.Length));
            //}
            //else
            //{
            //    ImageReference reference = tabImage.Parent.Reference;
            //    ImageTypeReference imageTypeReference = reference.ImageTypes[tabImage.ParentIndex];
            //    client.UploadImageDataAsync(tabImage.ImageGuid, reference.id, imageTypeReference.ImageAsStreamBuffer, cancel, process);
            //    OnUploadDataSent(new UploadDataSentArgs(imageTypeReference.ImageAsStreamBuffer.Length));
            //}
        }

        //private void UploadImageDataForLocalImageCompleted(object sender, UploadImageDataForLocalImageCompletedEventArgs e)
        //{
        //    if (e.Error != null)
        //    {
        //        OnUploadErrorOccurred(new UploadErrorOccurredEventArgs(e.Error.Message));
        //        return;
        //    }

        //    CompleteImageProcessing(e.Result);
        //}

        //private void UploadImageDataCompleted(object sender, UploadImageDataCompletedEventArgs e)
        //{
        //    if (e.Error != null)
        //    {
        //        OnUploadErrorOccurred(new UploadErrorOccurredEventArgs(e.Error.Message));
        //        return;
        //    }

        //    CompleteImageProcessing(e.Result);
        //}

        private void CompleteImageProcessing(long bytesReturned)
        {
            // notify that data was sent
            //OnUploadDataSent(new UploadDataSentArgs(bytesReturned));
            if (_canceling)
            {
                OnUploadCanceled();
            }
            else if (_processing)
            {
                OnUploadFinished();
            }
            else
            {
                // Not finished yet, continue uploading, unless a cancel has been requested
                bool cancel;
                lock (tabImage.SyncState)
                {
                    cancel = tabImage.SyncState.CancelRequested;
                }

                // set a flag to indicate that we are attempting to cancel the upload; this will tell the code above to check for
                // a successful cancel, and trigger the UploadCanceled event (if an error occurs, the error event is triggered instead).
                if (cancel)
                {
                    _canceling = true;
                    // send a request with the cancel flag set to true, which gives the server an opportunity to clean up
                    StartUpload(true, false);
                }
                else
                {
                    // if all data has been sent, see if there is a file processor and send a request to do the processing;
                    // the next file can begin uploading while a file is being processed, but the file is not set to Finished
                    // until processing has completed
                    if (!string.IsNullOrEmpty(_uploadedFileProcessorType))
                    {
                        // send a request that will do post-processing
                        _processing = true;
                        StartUpload(false, true);
                        OnUploadProcessingStarted();
                    }
                    else
                    {
                        // upload finished, and there is no post-processing type specified, so we're done
                        OnUploadFinished();
                    }
                }
            }
        }
    }
}